<?php
/**
 * @package PWE.modele
 * @author Gmax <gmaxfr78@gmail.com>
 */
class modele_category extends modele{
    protected static $_table = 'category';
    public $type = 'category';

    private $_id;
    private $_title;
    private $_permalien;
    private $_template;
    private $_parent_id = 0;
    private $_parent = null;
    protected $_discriminant = 'category';
    private $_media_id;
    private $_order_idx = 0;
    private $_media = null;
    private $_child = array();
    private $_statut_id = 2;
    private $_statut;
    private $_custom_vars = null;
    
    function __construct($id=null){
        if($id!==null){
            $this->_id = $id;
            $this->_constructObject();
        }
    }
    private function _constructObject(){
        $sqlQuery = 'SELECT ';
        $sqlQuery .= 't.*, s.nom AS statut ';
        $sqlQuery .= 'FROM '.self::getTable().' as t ';
        $sqlQuery .= 'LEFT JOIN '.PWE::getPrefixBdd().'statut AS s ON s.id = t.statut_id ';
        $sqlQuery .= 'WHERE t.id='.$this->_id.' ';
        $sqlQuery .= 'LIMIT 1';
        
        $datas = $this->_getOneResult($sqlQuery);
        if($datas){
            $this->_title =  $datas['title'];
            $this->_discriminant = $datas['discriminant'];
            $this->_permalien = new modele_permalien($this->_discriminant,$this->_id);
            $this->_template = $datas['template'];
            $this->_parent_id = $datas['parent_id'];
            $this->_statut_id = $datas['statut_id'];
            $this->_statut = $datas['statut'];
            $this->_media_id = $datas['media_id']+0;
            $this->_order_idx = $datas['order_idx']+0;
            $this->_custom_vars = $datas['custom_vars'];
        }
    }
    public function haveParent(){
        return ($this->_parent_id>0)?true:false;
    }
    public function haveChild(){
        if(count($this->_child)>0) return true;
        else{
            $this->_child = self::getChildListe($this->getId());
            if(count($this->_child)>0) return true;
        }
        return false;
    }
    public function getId(){
        return $this->_id;
    }
    public function setId($id=0){
        $this->_id = $id;
    }
    /**
     * 1=>brouillon
     * 2=>publié
     * 3=>privé
     * @return int
     */
    public function getStatutId(){
        return $this->_statut_id;
    }
    public function getStatut($input=false){
        if($input)return $this->inputFormat($this->_statut);
        return $this->outputFormat($this->_statut);
    }
    /* verification de type */
    /**
     * indique si la category est une rubrique
     * @return boolean
     */
    public function isCategory(){
        return ($this->_discriminant==='category')?true:false;
    }
    /**
     * indique si la category est une rubrique
     * @return boolean
     */
    public function isTag(){
        return ($this->_discriminant==='tag')?true:false;
    }
    /**
     * indique si la category est une page
     * @return boolean
     */
    public function isPage(){
        return ($this->_discriminant==='page')?true:false;
    }
    
    public function getTitle($input=false){
        if($input)return $this->inputFormat($this->_title);
        else return $this->outputFormat($this->_title);
    }
    public function getOrder(){
        return $this->_order_idx;
    }
    public function setOrder($order){
        if($order!=$this->_order_idx){
            $this->_order_idx = $order;
            $sql = 'UPDATE '.self::getTable().' SET order_idx='.$this->_order_idx.' WHERE id='.$this->getId();
            bdd_sql::doSql($sql);
        }
    }
    /**
     * @param type $input
     * @return \modele_permalien
     */
    public function getPermalien(){
        if($this->_permalien === null){
            if($this->_discriminant==='page')$this->_permalien = new modele_permalien('category');
            else $this->_permalien = new modele_permalien($this->_discriminant);
        }
        return $this->_permalien;
    }
    
    /**
     * renvoi l'URL complète de la catégorie
     * @return string
     */
    public function getUrl(){
        if($this->haveParent()){
            $parentUrl = $this->getParent()->getUrl();
        }else{
            $parentUrl = PWE::getBaseURL();
        }
        return $parentUrl.$this->getPermalien()->getLien().'/';
    }
    public function getTranslatedUrl($lang=''){
        if($this->haveParent()){
            $parentUrl = $this->getParent()->getTranslatedUrl($lang);
        }else{
            $parentUrl = PWE::getBaseURL();
        }
        return $parentUrl.$this->getPermalien()->getTranslatedLien($lang).'/';
    }
    
    /**
     * renvoi le template de page utilisé
     * @return string
     */
    public function getTemplate(){
        if($this->_template===''||$this->_template===null) $this->_template = PWE::getDefaultTemplate();
        return $this->_template;
    }
    
    /**
     * 
     * @return boolean
     */
    public function haveMedia(){
        return ($this->getMediaId()>0)?true:false;
    }
    /**
     * 
     * @return `\modele_media
     */
    public function getMedia($mediaId=0){
        if($this->_media===null){
            if($this->_media_id>0) $this->_media = new modele_media($this->_media_id);
            else $this->_media = new modele_media();
        }
        return $this->_media;
    }
    public function getMediaId(){
        return ($this->_media_id>0)?$this->_media_id:'NULL';
    }
    public function addMedia($mediaId){
        $this->setDatas(array('_media_id'=>$mediaId));
        $sqlQuery = 'UPDATE '.self::getTable().' SET ';
        $sqlQuery .= 'media_id='.$this->getMediaId().' ';
        $sqlQuery .= 'WHERE id='.$this->getId().' LIMIT 1';

        bdd_sql::doSql($sqlQuery,false);

        return true;
    }
    public function removeMedia($mediaId){
        $this->setDatas(array('_media_id'=>0));
        $sqlQuery = 'UPDATE '.self::getTable().' SET ';
        $sqlQuery .= 'media_id='.$this->getMediaId().' ';
        $sqlQuery .= 'WHERE id='.$this->getId().' LIMIT 1';

        bdd_sql::doSql($sqlQuery,false);

        return true;
    }
    /**
     * @deprecated utiliser getParent()
     * @return /modele_category|null
     */
    public function getCategory(){
        return $this->getParent();
    }
    /**
     * @deprecated utiliser getParentId()
     * @return int|string
     */
    public function getCategoryId(){
        return $this->getParentId();
    }
    /**
     * renvoi le modele parent ou null
     * @return /modele_category|null
     */
    public function getParent(){
        if($this->_parent===null){
            $this->_parent = ($this->_parent_id>0)?new modele_category($this->_parent_id):null;
        }
        return $this->_parent;
    }
    /**
     * renvoi l'id parent ou "NULL"
     * @return int|string
     */
    public function getParentId(){
        return ($this->_parent_id>0)?$this->_parent_id:"NULL";
    }
    public function getMenu($idMenu){
        $menu = modele_menu::isMenuExists($idMenu.'-'.$this->getPermalien()->getLien());
        if($menu===null && $this->haveParent() ){
            $menu = $this->getParent()->getMenu($idMenu);
        }
        return $menu;
    }
    /**
     * 
     * @return \modele_category array
     */
    public function getChild(){
        if($this->haveChild()){
            return $this->_child;
        }else{
            return array();
        }
    }
    public function getNombrePublications($public=false,$startDate=0,$endDate=0){
        if($this->isPage()){
            return 1;
        }else{
            return count($this->getPublications(0,0,$public,true,$startDate,$endDate));
        }
    }
    
    /**
     * 
     * @param int $start
     * @param int $limit
     * @param boolean $public
     * @param boolean $desc //tri par ordre inverse
     * @param timestamp $startDate //timestamp
     * @return \modele_publication
     */
    public function getPublications($start=0,$limit=0,$public=false,$desc=true,$startDate=0,$endDate=0){
        $retour = array();
        if($this->isPage()){
            $sqlQuery = 'SELECT id FROM '.modele_publication::getTable().' WHERE category_id='.$this->getId().' AND is_deleted=0 ';
            if($public) $sqlQuery .= 'AND statut_id=2 ';
            $data = $this->_getOneResult($sqlQuery);
            if($data){
                $retour[] = new modele_page($data['id']);
            }
        }else{
            $sqlQuery = 'SELECT t.id,t.order_idx,t.category_id,t.`date` FROM (';
            //articles
            $sqlQuery .= 'SELECT a.id,a.order_idx,a.category_id,a.`date` FROM '.modele_publication::getTable().' AS a WHERE a.category_id='.$this->getId().' AND a.is_deleted=0 ';
            if($public) $sqlQuery .= 'AND a.statut_id=2 ';
            
            if($startDate>0){
                $sqlQuery .= 'AND a.`date`>= "'.date('Y-m-d',$startDate).'" ';
            }
            if($endDate>0){
                $sqlQuery .= 'AND a.`date`<= "'.date('Y-m-d',$endDate).'" ';
            }
            //pages
            $sqlQuery .= 'UNION SELECT p.id,p.order_idx,p.category_id,p.`date` FROM '.modele_publication::getTable().' AS p LEFT JOIN '.self::getTable().' AS c ON c.parent_id='.$this->getId().' WHERE c.discriminant="page" AND p.category_id=c.id AND p.is_deleted=0 ';
            if($public) $sqlQuery .= 'AND p.statut_id=2 ';
            
            if($startDate>0){
                $sqlQuery .= 'AND p.`date`>= "'.date('Y-m-d',$startDate).'" ';
            }
            if($endDate>0){
                $sqlQuery .= 'AND p.`date`<= "'.date('Y-m-d',$endDate).'" ';
            }
            
            $sqlQuery .= ') AS t ORDER BY t.order_idx, t.`date` ';
            $sqlQuery .= ($desc===true)?'DESC':'ASC';
            if($limit>0){
                $sqlQuery .= ' LIMIT '.$start.','.$limit.' ';
            }
            
            $datas = $this->_getResults($sqlQuery);
            if($datas){
                foreach( $datas['results'] as $publicationId ){
                    if($this->isPage()){
                        $retour[] = new modele_page($publicationId['id']);
                    }else{
                        $retour[] = new modele_publication($publicationId['id']);
                    }
                }
            }
        }
        return $retour;
    }
    public function getTitreSEO() {
        return $this->getPermalien()->getTitre();
    }
    public function getDescriptionSEO() {
        return $this->getPermalien()->getDescription();
    }
    public function getCustomVars($input=false){
        $retour = array();
        if($this->_custom_vars != null){
            $customVars = unserialize($this->_custom_vars);
            if(count($customVars)>0){
                foreach($customVars as $k=>$v){
                    if(!$input){
                        $retour[$k]=stripslashes($this->outputFormat($v));
                        
                    }else{
                        $retour[$k]=stripslashes($v);
                    }
                }
            }
        }
        return $retour;
    }
    /**
     * renvoi la valeur d'une custom var
     * @param string $var
     * @param boolean $input
     * @return string
     */
    public function getCustomVar($var,$input=false){
        $vars = $this->getCustomVars($input);
        return (isset($vars) && isset($vars[$var]))?$vars[$var]:'';
    }
    
    public function setCustomVar($name,$value){
        $customVars = $this->getCustomVars();
        $customVars[$name] = $value;
        $toSerialize = array();
        foreach ($customVars as $k=>$v){
            $toSerialize[$k] = str_replace(array("\n","\r","\\","'"),array('','','',"&#39;"),$this->inputFormat($v));
        }
        $this->_custom_vars = serialize($toSerialize);
        $sql = 'UPDATE '.self::getTable()." SET custom_vars='".$this->_custom_vars."'";
        $sql .= 'WHERE id='.$this->getId().' LIMIT 1';
        bdd_sql::doSql($sql,false);
        return true;
    }
    
    public function getDatas($input=false){
        $datas = array(
            'id'=>$this->getId(),
            'title'=>$this->getTitle($input),
            'titre_seo'=>$this->getPermalien()->getTitre($input),
            'description_seo'=>$this->getPermalien()->getDescription($input),
            'permalien'=>$this->getPermalien()->getLien(),
            'url'=>$this->getUrl(),
            'parent_id'=>$this->getParentId(),
            'is_page'=>$this->isPage(),
            'is_tag'=>$this->isTag(),
            'media'=>$this->getMedia(),
            'order_idx'=>$this->getOrder(),
            'custom_vars'=>$this->getCustomVars($input),
            'template'=>$this->getTemplate(),
            'statut_id'=>$this->getStatutId(),
            'statut'=>$this->getStatut(),
            'modele'=>'category',
            'type'=>'category'
        );
        return $datas;
    }
    public function setDatas($datas) {
        foreach($datas as $k=>$v){
            if(substr($k, 0, 1) !== '_') $k = '_'.$k;
            if($k != '_id' && property_exists('modele_category',$k)){
                if($k=='_custom_vars'){
                    if(count($v)>0){
                        $cv = $this->getCustomVars();
                        foreach($v as $sk=>$sv){
                            $cv[$sk]=str_replace(array("\n","\r","\\","'"),array('','','',"&#39;"),$this->inputFormat($sv));
                        }
                        $this->$k=serialize($cv);
                    }
                }else{
                    $this->$k = $v;
                }
            }
        }        
        $this->getPermalien()->setDatas($datas);
        
        return true;
    }
    public function save() {
        $sqlQuery = 'INSERT INTO '.self::getTable().' ';
        $sqlQuery .= '(`title`,discriminant,template,custom_vars,parent_id,statut_id) ';
        $sqlQuery .= 'VALUES (';
        $sqlQuery .= '"'.$this->getTitle(true).'",';
        $sqlQuery .= '"'.$this->_discriminant.'",';
        $sqlQuery .= '"'.$this->getTemplate().'",';
        $sqlQuery .= "'".$this->_custom_vars."',";
        $sqlQuery .= $this->getParentId().',';
        $sqlQuery .= $this->getStatutId();
        $sqlQuery .= ')';
        
        bdd_sql::doSql($sqlQuery,false);
        $this->setId(bdd_sql::getLastInsertId());
        
        //permalien
        if($this->_discriminant!=='page'){
            $this->getPermalien()->setDatas(array('_modele'=>$this->_discriminant,'_modele_id'=>$this->getId()));
            $this->getPermalien()->save();
        }

        return array('success'=>true,'datas'=>$this->getDatas());
    }
    public function update() {
        $sqlQuery = 'UPDATE '.self::getTable().' SET ';
        $sqlQuery .= '`title`="'.$this->getTitle(true).'", ';
        $sqlQuery .= 'template="'.$this->getTemplate().'", ';
        $sqlQuery .= "custom_vars='".$this->_custom_vars."', ";
        $sqlQuery .= 'media_id='.$this->getMediaId().', ';
        $sqlQuery .= 'order_idx='.$this->getOrder().', ';
        $sqlQuery .= 'statut_id='.$this->getStatutId().', ';
        $sqlQuery .= 'parent_id='.$this->getParentId().' ';
        $sqlQuery .= 'WHERE id='.$this->getId().' LIMIT 1';

        bdd_sql::doSql($sqlQuery,false);
        if($this->_discriminant!=='page'){
            $this->getPermalien()->update();
        }

        return array('success'=>true,'datas'=>$this->getDatas());
        
    }
    
    public function delete() {
        // hierarchie
        if($this->haveChild()){
            foreach ($this->getChild() as $child){
                $child->delete();
            }
        }
        if($this->getNombrePublications()>0){
            foreach ($this->getPublications() as $publications){
                $publications->delete();
            }
        }
        
        // entree en bdd
        $sqlDelete = 'DELETE FROM '.self::getTable().' WHERE id='.$this->getId();
        bdd_sql::doSql($sqlDelete,false);
        
        //permalien
        if($this->getPermalien()!==null){
            $this->getPermalien()->delete();
        }
        return array('success'=>true,'datas'=>array());
    }
    /* methodes statiques */
    /**
     * 
     * @return string
     */
    public static function getTable(){
        return PWE::getPrefixBdd().self::$_table;
    }
    
    public static function getListe($start = 0){
        $sqlQuery = 'SELECT id FROM '.self::getTable().' ORDER BY order_idx,id DESC';
        if($start>0){
            $sqlQuery .=  ''; // TODO pagination
        }
        $retour = array();
        $results = bdd_sql::doSql($sqlQuery,true);
        if($results['count']>0){
            foreach($results['results'] as $categoryData){
                $retour[] = new modele_category($categoryData['id']);
            }
        }
        return $retour;
    }
    /**
     * renvoi la liste des catégories de premier niveau => sans parent
     * @param int $start
     * @param int $limit
     * @return \modele_category
     */
    public static function getPrimaryListe($start=0,$limit=0){
        $sqlQuery = 'SELECT id FROM '.self::getTable().' WHERE parent_id IS NULL AND discriminant="category" ORDER BY order_idx,id DESC';
        if($limit>0){
            $sqlQuery .=  ' LIMIT '.$start.','.$limit;
        }
        $retour = array();
        $results = bdd_sql::doSql($sqlQuery,true);
        if($results['count']>0){
            foreach($results['results'] as $categoryData){
                $retour[] = new modele_category($categoryData['id']);
            }
        }
        return $retour;
    }
    /**
     * 
     * @param type $parent_id
     * @param type $start
     * @param type $limit
     * @return \modele_category|\modele_page
     */
    public static function getChildListe($parent_id,$start = 0,$limit = 0){
        $sqlQuery = 'SELECT id, discriminant FROM '.self::getTable().' WHERE parent_id='.$parent_id.' ORDER BY order_idx,id DESC';
        if($start>0){
            $sqlQuery .=  ' LIMIT '.$start.', '.$limit;
        }
        $retour = array();
        $results = bdd_sql::doSql($sqlQuery,true);
        if($results['count']>0){
            foreach($results['results'] as $categoryData){
                if($categoryData['discriminant']==='page'){
                    $sqlPage = 'SELECT id FROM '.modele_page::getTable().' WHERE category_id='.$categoryData['id'].' LIMIT 1';
                    $resultPage = bdd_sql::doSql($sqlPage,true);
                    if($resultPage['count']==1){
                        $retour[] = new modele_page($resultPage['results'][0]['id']);
                    }
                }else{
                     $retour[] = new modele_category($categoryData['id']);
                }
            }
        }
        return $retour;
    }    
    
    /**
     * renvoi la category selon le permalien indiqué
     * @param string $permalien
     * @param string $modele
     * @param boolean $redirectionAuto
     * @return \modele_category
     */
    public static function findByPermalien($permalien,$modele='category',$redirectionAuto=true){
        return parent::findByPermalien($permalien,$modele,$redirectionAuto);
    }
}